import Cocoa
import FlutterMacOS
import CoreWLAN
import CoreLocation

public class WifiPlugin: NSObject, FlutterPlugin, CLLocationManagerDelegate {

    private let locationManager = CLLocationManager()
    private var pendingScanResult: FlutterResult?
    private var isLocationReady = false
    private var onLocationReady: (() -> Void)?

    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "wifi_plugin", binaryMessenger: registrar.messenger)
        let instance = WifiPlugin()
        registrar.addMethodCallDelegate(instance, channel: channel)
    }

    // 选一个可用的 Wi‑Fi 接口（优先取已上电）
    private func activeWifiInterface() -> CWInterface? {
        let client = CWWiFiClient.shared()
        if let ifaces = client.interfaces(), !ifaces.isEmpty {
            if let powered = ifaces.first(where: { $0.powerOn() }) { return powered }
            return ifaces.first
        }
        return client.interface()
    }

    // ===== 定位授权处理 =====
    private func ensureLocation(_ completion: @escaping () -> Void) {
        let status = CLLocationManager.authorizationStatus()
        if status == .authorized {
            isLocationReady = true
            completion(); return
        }
        onLocationReady = completion
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
        if #available(macOS 10.15, *) { locationManager.requestWhenInUseAuthorization() }
        locationManager.startUpdatingLocation()
    }

    public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorized { isLocationReady = true; manager.stopUpdatingLocation(); onLocationReady?(); onLocationReady = nil }
    }
    public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { manager.stopUpdatingLocation() }
    public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { /* no-op */ }
    // ======================

    // 扫描（按 SSID 去重，保留 RSSI 最强）
    private func doScan(_ result: @escaping FlutterResult) {
        guard let iface = activeWifiInterface() else {
            result(FlutterError(code: "NO_IFACE", message: "未找到可用的 Wi‑Fi 接口", details: nil)); return
        }
        guard iface.powerOn() else {
            result(FlutterError(code: "WIFI_OFF", message: "Wi‑Fi 未开启，请先在系统 Wi‑Fi 打开", details: nil)); return
        }
        DispatchQueue.global(qos: .userInitiated).async {
            do {
                let set = try iface.scanForNetworks(withName: nil, includeHidden: false)
                var bestBySSID: [String: CWNetwork] = [:]
                for n in set { if let s = n.ssid { if let old = bestBySSID[s] { if n.rssiValue > old.rssiValue { bestBySSID[s] = n } } else { bestBySSID[s] = n } } }
                var list: [[String: Any]] = []
                list.reserveCapacity(bestBySSID.count)
                for (ssid, net) in bestBySSID { list.append(["ssid": ssid, "isOpen": net.supportsSecurity(.none), "rssi": net.rssiValue, "bssid":net.bssid]) }
                list.sort { let ao = ($0["isOpen"] as? Bool) ?? false; let bo = ($1["isOpen"] as? Bool) ?? false; if ao != bo { return ao && !bo } ; return (($0["rssi"] as? Int) ?? Int.min) > (($1["rssi"] as? Int) ?? Int.min) }
                DispatchQueue.main.async { result(list) }
            } catch {
                DispatchQueue.main.async { result(FlutterError(code: "SCAN_FAILED", message: "Wi‑Fi 扫描失败：\(error.localizedDescription)", details: nil)) }
            }
        }
    }

    // 连接（密码可为空 → 开放网络）
    private func connect(ssid: String, password: String?, _ result: @escaping FlutterResult) {
        guard let iface = activeWifiInterface() else { result(false); return }
        guard iface.powerOn() else { result(false); return }
        DispatchQueue.global(qos: .userInitiated).async {
            do {
              NSLog("connect ssid: \(ssid)")
                let candidates = try iface.scanForNetworks(withName: ssid, includeHidden: false)
                guard let target = candidates.max(by: { $0.rssiValue < $1.rssiValue }) else { DispatchQueue.main.async { result(false) }; return }
                try iface.associate(to: target, password: (password?.isEmpty == false) ? password : nil)
                DispatchQueue.main.async { result(true) }
            } catch {
              NSLog("connect failed: \(error)")
                DispatchQueue.main.async { result(false) }
            }
        }
    }

    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        switch call.method {
        case "scanNetworks":
            ensureLocation { self.doScan(result) }
            if !isLocationReady { pendingScanResult = result }
        case "connectWithPassword":
            guard let args = call.arguments as? [String: Any], let ssid = args["ssid"] as? String else {
                result(FlutterError(code: "INVALID_ARGS", message: "需要提供 ssid/password", details: nil)); return
            }
            let pwd = args["password"] as? String
            connect(ssid: ssid, password: pwd, result)
        default:
            result(FlutterMethodNotImplemented)
        }
    }
}
